
//require('../shared/model'); //For Vec

function StateBuffer() {
    this.data = new Array(60);
    this.headFrameId = 0;
    this.index = 0;
}

StateBuffer.prototype.add = function(state) {
    this.index++;
    if (this.index == 60)
        this.index = 0;
    
    this.data[this.index] = state;
    this.headFrameId = state.frameId;
};

StateBuffer.prototype.iterator = function(fromFrameId) {
    return new StateBufferIterator(this, fromFrameId);
};

function StateBufferEntry(frameId, phyObj, keys, haltedTicks, forwardVec) {
    this.frameId = frameId;
    this.phyObj = phyObj;
    this.keys = keys;
    
    this.upVec = Vec();
    this.forwardVec = forwardVec;
    this.rightVec = Vec();
    this.centerVec = Vec();
    this.haltedTicks = 0;
};

//Inherit methods. Makes life easier...
StateBufferEntry.prototype = Object.create(Car.prototype);

StateBufferEntry.prototype.clone = function() {
    var clone = new StateBufferEntry(this.frameId, this.phyObj.clone(),this.keys);
    clone.upVec = this.upVec.clone();
    clone.rightVec = this.rightVec.clone();
    clone.forwardVec = this.forwardVec.clone();
    clone.centerVec = this.centerVec.clone();
    clone.haltedTicks = this.haltedTicks;
    return clone;
}

function StateBufferIterator(stateBuffer, frameId) {
    this.stateBuffer = stateBuffer;
    
    var diff = stateBuffer.headFrameId - frameId;
    if (diff > 59)
        throw 'Too old';
    
    this.correctFrame = stateBuffer.index - diff;
    this.index = this.correctFrame + 1;
    if (this.correctFrame < 0)
        this.correctFrame += 60;
    if (this.index < 0)
        this.index += 60;
    else if (this.index === 60)
        this.index = 0;
    
    this.startIndex = this.index;
    this.endIndex = stateBuffer.index + 1;
    if (this.endIndex === 60)
        this.endIndex = 0;
}

StateBufferIterator.prototype.next = function() {
    var sb = this.stateBuffer.data, curr, next;
    if (this.index === this.startIndex) {
        var sf = sb[this.startIndex],
            sc = sb[this.correctFrame];
        sf.phyObj = sc.phyObj.clone();
        sf.keys = sc.keys;
        sf.forwardVec = sc.forwardVec.clone();
        
        this.index++;
        if (this.index === 60)
            this.index = 0;
        return sb[this.startIndex];
    }
    
    if (this.index === this.endIndex)
        return null;
    
    var lastIndex = this.index - 1;
    if (lastIndex === -1)
        lastIndex = 59;
    
    // Clone the current state into the next one,
    // correcting state "in-place".
    // frameId should of course be correct anyways.
    sb[this.index].phyObj = sb[lastIndex].phyObj.clone();
    sb[this.index].haltedTicks = sb[lastIndex].haltedTicks;
    sb[this.index].keys = sb[lastIndex].keys;
    sb[this.index].upVec = sb[lastIndex].upVec.clone();
    sb[this.index].rightVec = sb[lastIndex].rightVec.clone();
    sb[this.index].forwardVec = sb[lastIndex].forwardVec.clone();
    sb[this.index].centerVec = sb[lastIndex].centerVec.clone();
    
    var idx = this.index;
    this.index++;
    if (this.index === 60)
        this.index = 0;
    
    return sb[idx];   
};

module.exports.StateBuffer = StateBuffer;
module.exports.StateBufferEntry = StateBufferEntry;

module.exports.testdata = function() {
    require('../shared/model');
    global.buf = new StateBuffer();
    for (var i = 0; i < 100; ++i)
        buf.add(new StateBufferEntry(i, new PhyObj, 0));
    
}